#include "recvcanprotmanager.h"

#include <QDir>
#include <QFile>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QDebug>

bool RecvCANProtManager::loadConfig(const QString& filePath) {
    QFile file(filePath);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        qWarning() << "无法打开配置文件:" << filePath;
        return false;
    }

    QByteArray data = file.readAll();
    QJsonDocument doc = QJsonDocument::fromJson(data);
    if (doc.isNull()) {
        qWarning() << "JSON解析失败";
        return false;
    }

    QJsonObject root = doc.object();
    QJsonArray messages = root["protocols"].toArray();

    for (const auto& msgVal : messages) {
        QJsonObject msgObj = msgVal.toObject();
        CanMessage message;

        // 解析报文基本信息
        message.msgName = msgObj["msgName"].toString();
        message.msgType = msgObj["msgType"].toString();
        message.msgId = msgObj["msgId"].toString().toUInt(nullptr, 16);  // 解析16进制ID
        message.msgSendType = msgObj["msgSendType"].toString();
        message.msgCycleTime = msgObj["msgCycleTime"].toInt();
        message.msgLength = msgObj["msgLength"].toInt();

        // 解析信号列表
        QJsonArray signalsList = msgObj["signals"].toArray();
        for (const auto& sigVal : signalsList) {
            QJsonObject sigObj = sigVal.toObject();
            CanSignal signal;

            signal.signalName = sigObj["signalName"].toString();
            signal.signalDescription = sigObj["signalDescription"].toString();
            signal.byteOrder = sigObj["byteOrder"].toString();
            signal.startByte = sigObj["startByte"].toInt();
            signal.startBit = sigObj["startBit"].toInt();
            signal.signalSendType = sigObj["signalSendType"].toString();
            signal.bitLength = sigObj["bitLength"].toInt();
            signal.dataType = sigObj["dataType"].toString();
            signal.resolution = sigObj["resolution"].toDouble();
            signal.offset = sigObj["offset"].toDouble();
            signal.minPhys = sigObj["minPhys"].toDouble();
            signal.maxPhys = sigObj["maxPhys"].toDouble();
            signal.minHex = sigObj["minHex"].toString().toULongLong(nullptr, 16);
            signal.maxHex = sigObj["maxHex"].toString().toULongLong(nullptr, 16);
            signal.initialValue = sigObj["initialValue"].toString().toULongLong(nullptr, 16);
            signal.unit = sigObj["unit"].toString();

            // 解析信号值描述
//            QJsonObject valDescs = sigObj["valueDescriptions"].toObject();
//            for (auto it = valDescs.begin(); it != valDescs.end(); ++it) {
//                quint64 key = it.key().toULongLong(nullptr, 16);
//                signal.valueDescs[key] = it.value().toString();
//            }

            message.signalsL.append(signal);
        }

        m_msgMap[message.msgId] = message;
    }

    qInfo() << "PCAN接收报文配置加载成功，共加载" << m_msgMap.size() << "个报文";
    return true;
}

const CanMessage* RecvCANProtManager::findMessage(quint32 msgId) const {
    auto it = m_msgMap.find(msgId);
    return (it != m_msgMap.end()) ? &(it.value()) : nullptr;
}

quint64 RecvCANProtManager::extractRawValue(const CanSignal& signal, const QByteArray& data) const {
    quint64 rawValue = 0;
    int totalBits = data.size() * 8;

    // 检查数据长度是否足够
    if (signal.startBit + signal.bitLength > totalBits) {
        qWarning() << "信号" << signal.signalName << "解析越界";
        return 0;
    }

    if ( signal.byteOrder.contains("Motorola", Qt::CaseInsensitive) ) {  // 大端模式

        // for (int i = 0; i < signal.bitLength; ++i) {
        //     int bitPos = signal.startBit + i;
        //     int byteIdx = bitPos / 8;
        //     int bitInByte = bitPos % 8;  // Intel位序(低位在前)

        //     if (byteIdx >= data.size())
        //         break;
        //     quint8 byte = static_cast<quint8>(data[byteIdx]);
        //     if (byte & (1 << bitInByte)) {
        //         rawValue |= (1ULL << i);
        //     }
        // }
        int startByte = signal.startByte;
        int startBit = signal.startBit;
        int bitLength = signal.bitLength;

        const int extractByteCount = bitLength / 8;

        for (int byteOffset = 0; byteOffset < extractByteCount; ++byteOffset) {
            int currByteIdx = startByte - byteOffset;
            quint8 currByte = static_cast<quint8>(data[currByteIdx]); // 当前字节值

            for (int bitOffset = 0; bitOffset < 8; ++bitOffset) {
                int totalBitIdx = byteOffset * 8 + bitOffset;
                if (totalBitIdx >= bitLength) break;

                bool isSet = (currByte & (1 << bitOffset)) != 0;
                if (isSet) {
                    rawValue |= (1ULL << totalBitIdx);
                }

                //            int globalBitPos = currByteIdx * 8 + bitOffset; // 全局位位置（辅助理解）
                //            qDebug() << QString("总提取位索引: %1, 位位置: %2, 字节索引: %3, "
                //                               "字节值: 0x%4, 字节内位: %5, 是否为1: %6, 当前值: 0x%7（十进制: %8）")
                //                        .arg(totalBitIdx)
                //                        .arg(globalBitPos)
                //                        .arg(currByteIdx)
                //                        .arg(QString::number(currByte, 16).toUpper().rightJustified(2, '0'))
                //                        .arg(bitOffset)
                //                        .arg(isSet ? "是" : "否")
                //                        .arg(QString::number(rawValue, 16).toUpper().rightJustified(4, '0'))
                //                        .arg(rawValue);
            }
        }
        if(extractByteCount>0)
            return rawValue;

       for (int i = 0; i < signal.bitLength; ++i) {
           int bitPos = signal.startBit + i;
           int byteIdx = bitPos / 8;
           int bitInByte = bitPos % 8;  // Intel位序(低位在前)

           if (byteIdx >= data.size())
               break;
           quint8 byte = static_cast<quint8>(data[byteIdx]);
           if (byte & (1 << bitInByte)) {
               rawValue |= (1ULL << i);
           }
       }

    }
    else {  // Intel小端模式
        for (int i = 0; i < signal.bitLength; ++i) {
            int bitPos = signal.startBit + i;
            int byteIdx = bitPos / 8;
            int bitInByte = 7 - (bitPos % 8);  // Motorola位序(高位在前)

            if (byteIdx >= data.size())
                break;
            quint8 byte = static_cast<quint8>(data[byteIdx]);
            if (byte & (1 << bitInByte)) {
                rawValue |= (1ULL << (signal.bitLength - 1 - i));
            }
        }
    }

    return rawValue;
}

bool RecvCANProtManager::parseSignal(const CanSignal& signal, const QByteArray& data,
                                   double& physValue, QString& valueDesc) const {
    // 提取原始值
    quint64 rawValue = extractRawValue(signal, data);

    // 校验原始值范围
    if (rawValue < signal.minHex || rawValue > signal.maxHex)
    {
        qWarning() << "信号" << signal.signalName << "原始值超出范围:" << rawValue;
        return false;
    }

    // 计算物理值
    physValue = rawValue * signal.resolution + signal.offset;

    // 获取值描述
    if (signal.valueDescs.contains(rawValue)) {
        valueDesc = signal.valueDescs[rawValue];
    } else {
        valueDesc = " ";
    }

    return true;
}
